#ifndef ESTRATEGIAALMACENAMIENTO_H_
#define ESTRATEGIAALMACENAMIENTO_H_

#include "Clave.h"
#include "Almacenamiento.h"
#include "Bloque.h"
#include "Registro.h"
#include "WrapperComponente.h"


namespace Toolkit
{

class EstrategiaAlmacenamiento
{
public:
    EstrategiaAlmacenamiento(const unsigned long int &tamanoBloque);
    virtual ~EstrategiaAlmacenamiento();

    /**
     * Se almacena el dato indicado en el almacenamiento.
     * Si su serialización excede el tamaño especificado para el almacenamiento, 
     * se arroja una excepción.
     */
    virtual unsigned long int guardarDato (Almacenamiento &almacenamiento, const Dato &dato,
                    const Clave &clave, WrapperComponente &wrapper) = 0;

    /**
     * Se reemplaza el dato cuya clave se pasa y que se encuentra en la posición dada,
     * por aquel pasado como parámetro. Se devuelve la posición en que se guarda nuevamente 
     * (depende la estrategia, es posible que se haga necesario ubicarlo en una nueva posición
     * dentro del almacenamiento). 
     * Si la serialización del dato excede el tamaño especificado para el almacenamiento, 
     * se arroja una excepción.
     */
    virtual unsigned long int modificarDato (Almacenamiento &almacenamiento, const Dato &dato, 
    			const Clave &clave, const unsigned long int posicion, WrapperComponente &wrapper) = 0;

    /**
     * Se devuelve en el dato pasado aquel cuya clave es la especificada, tras buscarlo en la posición
     * especificada del almacenamiento. 
     * Si la clave no está en la posición indicada, se devuelve false.
     */    
    virtual bool recuperarDato (Almacenamiento &almacenamiento, const unsigned long int posicion, 
    				Dato &dato, const Clave &clave, WrapperComponente &wrapper) = 0;

    /**
     * Se elimina del almacenamiento el dato cuya clave es pasada (que se busca en la posición especificada),
     * y se lo devuelve en el dato pasado.
     */
    virtual void eliminarDato (Almacenamiento &almacenamiento, const long unsigned int posicion,
                    Dato &dato, const Clave &clave, WrapperComponente &wrapper) = 0;
                    
	
	/**     
     * Se busca uno por uno en los registros del almacenamiento la clave especificada.
     * Si se la encuentra se devuelve true y se hidrata el dato pasado con la información
     * almacenada. La posición en el almacenamiento es guardada en la variable posicion.
     * Si no se lo encuentra se devuelve false. 
     * */ 
    virtual bool busquedaSecuencial(Almacenamiento &almacenamiento,
    			Dato &dato, const Clave &clave, unsigned long int &posicion,
    			WrapperComponente &wrapper);
    			
	/**
	 * Se recupera del almacenamiento el componente en la posición pasada, y se lo devuelve dentro del
	 * wrapper. LA MEMORIA ASOCIADA A ESE COMPONENTE DEBE SER LIBERADA POR EL QUE LLAME AL METODo.	 
	 * */    			
    virtual void recuperarComponente(Almacenamiento &almacenamiento, const unsigned long int &posicion, 
    		WrapperComponente &wrapper) = 0;
    
    /**
     * Se persiste el componente contenido por el wrapper, en la posicion especificada. 
     * */
    virtual void guardarComponente(Almacenamiento &almacenamiento, const unsigned long int &posicion, 
    		WrapperComponente &wrapper) = 0;
    		
    /**
     * Se persiste el componente contenido por el wrapper. 
     * */
    virtual unsigned long int guardarComponente(Almacenamiento &almacenamiento, WrapperComponente &wrapper) = 0;

    virtual void eliminarComponente(Almacenamiento &almacenamiento, const unsigned long int &posicion,
    		WrapperComponente &wrapper) = 0;

protected:	
	unsigned long int tamanoBloque;
	
	/**
	 * Dato auxiliar que se copia para no depender del usuario del toolkit ante la necesidad
	 * de usar alguno de sus métodos.
	 *
	 * */
	Dato *datoAuxiliar;

};

}

#endif /* ESTRATEGIAALMACENAMIENTO_H_ */
